package com.siteseat.common.security;

import java.io.Console;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

import org.apache.commons.io.IOUtils;

import com.siteseat.common.misc.FileHelper;

/**
 *
 */
public class PasswordFileHelper {

  private File passwordFile;
  
  /**
   * 
   *
   *
   * @param passwordFile
   */
  public PasswordFileHelper( String passwordFilePath ) {
    this.passwordFile = new File(passwordFilePath);    
  }
  
  /**
   * Gets the passwordFile
   *
   * @return the passwordFile
   */
  public File getPasswordFile() {
    return passwordFile;
  }
  
  /**
   * 
   *
   * @param password
   * @return
   * @throws IOException
   */
  public boolean verify( String password ) throws IOException {
    if( doesPasswordFileExists() == false ) {
      return true;
    }
    
    byte[] buf = FileHelper.readIntoBytes( getPasswordFile() );
    return Arrays.equals( buf, Sha1Digest.digest( password ) );
  }

  public boolean doesPasswordFileExists() {
    File f = getPasswordFile();
    if( f == null || f.exists() == false ) {
      return false;
    }
    return true;
  }
  
  /**
   * 
   *
   * @return
   * @throws IOException
   */
  public boolean verify( boolean enforceConsoleMode ) throws IOException {
    Console cons = System.console();
    if( cons == null ) {
      if( enforceConsoleMode ) {
        throw new IOException( "Not in console mode" );
      }
      return true;
    }
    
    if( doesPasswordFileExists() == false ) {
      return true;
    }

    char[] psw = cons.readPassword( "%s", "Password:" );
    return verify( new String(psw) );
  }
  
  /**
   * 
   *
   * @param password
   * @throws IOException
   */
  public void generate() throws IOException {
    Console cons = System.console();
    if( cons == null ) {
      throw new IOException( "Only work under console mode" );
    }
    
    
    while( true ) {
      char[] psw = cons.readPassword( "%s", "Password:" );
      char[] again = cons.readPassword( "%s", "Confirmed:" );
      if( Arrays.equals( psw, again ) ) {
        generate( new String(psw) );
        return;
      }
      cons.writer().println( "Not matched. Please check and type again." );
    }
  }
  
  /**
   * @throws FileNotFoundException 
   * 
   */
  public void generate( String password ) throws IOException {
    
    byte[] digest = Sha1Digest.digest( password );
    
    File f = getPasswordFile();
    if( f.exists() ) {
      f.delete();
    }
    if( f.createNewFile() == false ) {
      throw new IOException( "Failed to create new file: " + f );
    }
    
    FileOutputStream fos = new FileOutputStream(f);
    try {
      fos.write( digest );
      fos.flush();
      fos.getFD().sync();
      System.console().writer().println( "Password is generated to " + f.getAbsolutePath() );
    } finally {
      IOUtils.closeQuietly( fos );
    }
  }

  /**
   *
   * @param args
   */
  public static void main( String[] args ) throws Exception {
    if( args.length != 1 ) {
      System.out.println( "Usage: javac -cp <...> " + com.siteseat.common.security.PasswordFileHelper.class.getName() + " <password file path>" );
      System.exit( 1 );
    }
    
    PasswordFileHelper ph = new PasswordFileHelper( args[0] );
    ph.generate();
  }

}
